2019/02/05

Recent entries from same category

  1. Go 言語プログラミングエッセンスという本を書きました。
  2. errors.Join が入った。
  3. unsafe.StringData、unsafe.String、unsafe.SliceData が入った。
  4. Re: Go言語で画像ファイルか確認してみる
  5. net/url に JoinPath が入った。

現在は設定ファイルを読み込む仕様に変更しました。詳細はリポジトリの README.md を参照下さい。

Language Server はとても便利なので最近ではコーディングの時は常に Language Server を有効にしているけど、全く要望が無い訳ではないです。

  • 好みの Lint でコードをチェックしたい
  • 特定言語の Language Server が無い
  • そもそも編集中のファイルがソースコードではない

例えば Vim script には現状、Language Server がありません。これは言語の特性上、パースし辛らかったり、型情報が全くないので補完候補を作り出せない等の理由もあります。でも補完よりもまず Language Server の Diagnostic が欲しいと思う訳です。

そこで、どんな言語であろうとも Lint ツールが grep と同様の形式で結果を出力してくれさえすれば Language Server にしてしまうコマンド efm-langserver を作りました。

GitHub - mattn/efm-langserver

efm-langserver General purpose Language Server that can use specified error message format generated...

https://github.com/mattn/efm-langserver

以下でインストール出来ます。

go get github.com/mattn/efm-langserver/cmd/efm-langserver

仕組みは haya14busa さんが reviewdog の Vim script 対応の際に Vim のオプション、errorformat をパースするライブラリ errorformat を作っておられたので、各 Lint コマンドが出力する行番号、列番号、メッセージをパース、その情報を Language Server Protocol でテキストエディタに教えてあげようという物です。なので

grep 形式の出力をする Lint ツールであれば Language Server になれてしまう訳です。

設定には若干、シェルスクリプト等の知識が必要になります。例えば ERB のファイルを編集するのであれば以下のコマンドでシンタックスチェックを行い grep 形式で出力出来ます。

$ cat foo.erb | erb -x -T - | ruby -c

ですので vim-lsp (Vim の Language Server Client) から使うには以下の様に設定します。(offsetを1にしているのはshebangを除ける為です)

augroup LspERB
  au!
  autocmd User lsp_setup call lsp#register_server({
      \ 'name''efm-langserver-erb',
      \ 'cmd'{server_info->['efm-langserver''-offset=1''-stdin', &shell, &shellcmdflag, 'erb -x -T - | ruby -c']},
      \ 'whitelist': ['eruby'],
      \ })
augroup END

動かすとこんな感じになります。

erb

また Vim script には vint という Lint ツールがあるので vim-lsp の設定は以下になります。

augroup LspVim
  au!
  autocmd User lsp_setup call lsp#register_server({
      \ 'name''efm-langserver-vim',
      \ 'cmd'{server_info->['efm-langserver''-stdin', &shell, &shellcmdflag, 'vint -']},
      \ 'whitelist': ['vim'],
      \ })
augroup END

エラーの出力形式が grep と少し違う場合には -efm というオプションで調整出来ます。詳しくは errorformat のページを参照して下さい。また Lint ツールが標準入力を読み込んでくれる場合は上記の様に -stdin オプションを付けますが、例えば make コマンドの様に標準入力を読んでくれないコマンドを使う場合はこのオプションを外して下さい。

Posted at by